package com.atguigu.demo.data;

/**
 * 环形队列的顺序表中为什么要空一个位置
 * 在循环中如果使用 rear - front 来计算队列长度，那么不能判断是满了还是空了
 *
 */
public class ArrayAroundQueue {

    /**
     * 队列的大小
     */
    int maxSize;

    /**
     * 用数组来实现队列
     */
    int[] arr;

    /**
     * 指向队首元素
     */
    int front;

    /**
     * 指向队尾元素的下一个元素
     */
    int rear;

    public ArrayAroundQueue(int maxSize) {
        this.maxSize = maxSize + 1;
        this.arr = new int[this.maxSize];
        // front 指向队列首元素的前一个位置
        this.front = 0;
        this.rear = 0;
    }

    /**
     * 如果尾指针的下一个位置和头指针相同，那么就是满了
     *
     * @return
     */
    public boolean isFull() {
        return (rear + 1) % maxSize == front;
    }

    /**
     * 如果队首元素和队尾元素的位置相同，那么就是空队列
     *
     * @return
     */
    public boolean isEmpty() {
        return front == rear;
    }

    public void addNum(int num) {
        if (isFull()) {
            System.out.println("队列已满，无法再进行入队操作");
            return;
        }
        // 先放入元素，再后移队尾标记
        arr[rear] = num;
        rear = (rear + 1) % maxSize;
    }

    public int getNum() {
        if (isEmpty()) {
            throw new RuntimeException("队列为空，无法出队");
        }

        // 队首标记后移，指向队首元素
        System.out.println("出队元素是：");
        int num = arr[front];
        front = (front + 1) % maxSize;
        return num;
    }

    public void showQueue() {
        if (isEmpty()) {
            throw new RuntimeException("队列为空，无法遍历");
        }
        System.out.println("遍历队列");
        // 当 front + 1 == rear 时停止遍历
        int start = front;
        while (start != rear) {
            System.out.println(arr[start]);
            start = (start + 1) % maxSize;
        }
    }

    public void getHead() {
        if (isEmpty()) {
            throw new RuntimeException("队列为空");
        }
        System.out.println("队首元素为：" + arr[front]);
    }

}
